/*
 * $Id: GraphicsUtil.java 182 2009-06-04 16:30:30Z meyer@alphatec.de $
 * 
 *
 * Copyright 2009 DeltaDesk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package deltadesk.apps.pictureviewer.util;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

/**
 * GraphicsUtil
 * 
 * @author Andreas Meyer
 * @version $Revision: 182 $
 */
public class GraphicsUtil {

	/**
	 * Fit rectangle into an other rectangle preserving its ratio.
	 * 
	 * @param parentWidth
	 * @param parentHeight
	 * @param childWidth
	 * @param childHeight
	 * @return
	 */
	public static Rectangle fitRectangleInto(final int parentWidth,
			                                 final int parentHeight,
			                                 final int childWidth,
			                                 final int childHeight) {
		
		return fitRectangleInto(parentWidth, parentHeight,
				                childWidth,  childHeight, true);
	}

	/**
	 * Fit rectangle into an other rectangle preserving its ratio.
	 * 
	 * @param parentWidth
	 * @param parentHeight
	 * @param childWidth
	 * @param childHeight
	 * @param scaleUp
	 * @return
	 */
	public static Rectangle fitRectangleInto(final int parentWidth,
                                             final int parentHeight,
                                             final int childWidth,
                                             final int childHeight,
			                                 final boolean scaleUp) {

		// child data
		final double ch = (double) childHeight;
		final double cw = (double) childWidth;

		// parent data
		final double ph = (double) parentHeight;
		final double pw = (double) parentWidth;

		// ratio
		final double widthRatio = pw / cw;
		final double heightRatio = ph / ch;

		final boolean willScaleUp = (childHeight < parentHeight) && 
		                            (childWidth < parentWidth);
		if(willScaleUp && !scaleUp) {
			
			final Point p = centerRectangle(parentWidth, parentHeight, 
					                        childWidth,  childHeight);
			return new Rectangle(p.x, p.y, childWidth, childHeight);
		}

		// determine scale mode
		if (widthRatio < heightRatio) {

			final int h = (int) (ch * widthRatio);
			final Point p = centerRectangle(parentWidth, parentHeight,
					                        parentWidth, h);
			return new Rectangle(p.x, p.y, parentWidth, h);
		} else if (widthRatio > heightRatio) {

			final int w = (int) (cw * heightRatio);
			final Point p = centerRectangle(parentWidth, parentHeight,
					                        w,           parentHeight);
			return new Rectangle(p.x, p.y, w, parentHeight);
		} else {

			return new Rectangle(parentWidth, parentHeight);
		}
	}

	/**
	 * Center a rectangle inside an other rectangle.
	 * 
	 * @param parentWidth
	 * @param parentHeight
	 * @param childWidth
	 * @param childHeight
	 * @return
	 */
	public static Point centerRectangle(final int parentWidth,
                                        final int parentHeight,
			                            final int childWidth,
			                            final int childHeight) {

		return new Point(
				(parentWidth - childWidth) / 2,
				(parentHeight - childHeight) / 2);
	}
	
	/**
	 * Resize the image.
	 * 
	 * @param img
	 * @param newW
	 * @param newH
	 * @param quality
	 * @return
	 */
	public static BufferedImage resize(final BufferedImage img,
			                                 final int newW,
			                                 final int newH,
			                                 final boolean quality) {

		final int w = img.getWidth();
		final int h = img.getHeight();
		
		if(w == newW && h == newH) {
			return img;
		}
		
		final BufferedImage dimg = new BufferedImage(newW, newH,
				BufferedImage.TYPE_INT_RGB);
		final Graphics2D g = dimg.createGraphics();
		
		if(quality) {

			g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			g.setRenderingHint(RenderingHints.KEY_RENDERING,
					RenderingHints.VALUE_RENDER_QUALITY);
		} // end if

		g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
		g.dispose();
		return dimg;
	}

	/**
	 * Sleep for specified amount of time.
	 * 
	 * @param amount
	 */
	public static void sleep(final long amount) {

		Thread.yield();
		
		if(amount <= 0) {
			return;
		}

		try {
			Thread.sleep(amount);
		} catch (Exception e) {}
	}

}
